module Date where

import Char
import qualified StringHelper
import Data.Time



data Date = Empty | Date Int Int Int deriving (Show,Read)-- dzien, miesiac, rok

instance Eq Date where
        date1 == date2     | getYear date1 /= getYear date2    = False
                           | getMonth date1 /= getMonth date2  = False
                           | getDay date1 /= getDay date2      = False
                           | otherwise                         = True
        date1 /= date2     = not (date1 == date2)

instance Ord Date where
        date1 < date2      | getYear date1 < getYear date2   = True
                           | getYear date1 > getYear date2   = False
                           | getMonth date1 < getMonth date2 = True  -- tutaj year1 == year2
                           | getMonth date1 > getMonth date2 = False
                           | getDay date1 < getDay date2     = True  -- tutaj month1 == month2
                           | getDay date1 > getDay date2     = False
                           | otherwise                       = False -- tutaj date1 == date2
        date1 <= date2     | getYear date1 < getYear date2   = True
                           | getYear date1 > getYear date2   = False
                           | getMonth date1 < getMonth date2 = True  -- tutaj year1 == year2
                           | getMonth date1 > getMonth date2 = False
                           | getDay date1 < getDay date2     = True  -- tutaj month1 == month2
                           | getDay date1 > getDay date2     = False
                           | otherwise                       = True -- tutaj date1 == date2
        date1 > date2      = not (date1 <= date2)
        date1 >= date2     = not (date1 < date2)

-- getters
getYear :: Date -> Int
getYear Empty = 0
getYear (Date d m y) = y

getMonth :: Date -> Int
getMonth Empty = 0
getMonth (Date d m y) = m

getDay :: Date -> Int
getDay Empty = 0
getDay (Date d m y) = d


fst3 (x, _, _) = x
snd3 (_, y, _) = y
thd3 (_, _, z) = z

getActualDateMinus :: Int -> IO (Maybe Date)
getActualDateMinus minusMonths =
        fmap (\x -> Just x) 
                (fmap (\x -> Date (thd3 x) (snd3 x) (fromIntegral(fst3 x)::Int)) 
                        utcDate)
        where iocal = fmap utctDay getCurrentTime
              utcDate = iocal >>= return . toGregorian . (addDays (fromIntegral(-minusMonths*30)::Integer))


constructFromString :: String -> Maybe Date
constructFromString str = 
        if (any (\x -> not ((isDigit x) || isSpace x) ) str) then
                Nothing
        else 
                if (length args) /= 3 then
                        Nothing
                else
                  case maybeYear of
                    Nothing   -> Nothing
                    Just year ->
                     case maybeMonth of
                       Nothing    -> Nothing
                       Just month ->
                        case maybeDay of
                          Nothing  -> Nothing
                          Just day ->
			    if (year > 2000 && year < 2100 && day > 0 && day < 32 && month > 0 && month < 13) then
	                        Just (Date day month year)
			    else
				Nothing
                   --where args = StringHelper.getWords (words str)
                   where args = words str
			 maybeYear = StringHelper.string2int(args!!2)
			 maybeMonth = StringHelper.string2int(args!!1)
                         maybeDay  = StringHelper.string2int(args!!0)

display :: Date -> String
display Empty = "-"
display date = (show(getDay date)) ++ "." ++ (show(getMonth date)) ++ "." ++ (show(getYear date))